/**
 * Copyright 2009-2017 the original author or authors.
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.baturu.mybatisminus;

import com.baturu.mybatisminus.exception.MybatisMinusException;
import com.baturu.mybatisminus.injector.BaseDaoSqlInjector;
import com.baturu.mybatisminus.injector.DefaultBaseDaoSqlInjector;
import com.baturu.mybatisminus.injector.DefaultMethodNameSqlInjector;
import com.baturu.mybatisminus.injector.MethodNameSqlInjector;
import org.apache.ibatis.binding.MapperRegistry;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.springframework.util.Assert;

/**
 * @author huangbin
 */
public class MinusConfiguration extends Configuration {

    /**
     * 表名下划线风格，优先于mapUnderscoreToCamelCase，
     * 如果未设置则取mapUnderscoreToCamelCase的值
     */
    private Boolean tableNameUnderLine;
    /**
     * 表字段名下划线风格，优先于mapUnderscoreToCamelCase，
     * 如果未设置则取mapUnderscoreToCamelCase的值
     */
    private Boolean columnNameUnderLine;

    /**
     * 是否输出自动生成的SQL到日志
     */
    private boolean showGeneratedSql = false;
    /**
     * BaseDao内置方法SQL注入器
     */
    private Class<? extends BaseDaoSqlInjector> baseDaoSqlInjectorClass = DefaultBaseDaoSqlInjector.class;
    /**
     * BaseDAO方法名SQL注入器
     */
    private Class<? extends MethodNameSqlInjector> methodNameSqlInjectorClass = DefaultMethodNameSqlInjector.class;


    public final MinusMapperRegistry mybatisMapperRegistry = new MinusMapperRegistry(this);


    public MinusConfiguration() {
    }

    @Override
    public MapperRegistry getMapperRegistry() {
        return mybatisMapperRegistry;
    }

    @Override
    public <T> void addMapper(Class<T> type) {
        mybatisMapperRegistry.addMapper(type);
    }

    @Override
    public void addMappers(String packageName, Class<?> superType) {
        mybatisMapperRegistry.addMappers(packageName, superType);
    }

    @Override
    public void addMappers(String packageName) {
        mybatisMapperRegistry.addMappers(packageName);
    }

    @Override
    public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        return mybatisMapperRegistry.getMapper(type, sqlSession);
    }

    @Override
    public boolean hasMapper(Class<?> type) {
        return mybatisMapperRegistry.hasMapper(type);
    }

    public Boolean getTableNameUnderLine() {
        return tableNameUnderLine != null ? tableNameUnderLine : mapUnderscoreToCamelCase;
    }

    public void setTableNameUnderLine(Boolean tableNameUnderLine) {
        this.tableNameUnderLine = tableNameUnderLine;
    }

    public Boolean getColumnNameUnderLine() {
        return columnNameUnderLine != null ? columnNameUnderLine : mapUnderscoreToCamelCase;
    }

    public void setColumnNameUnderLine(Boolean columnNameUnderLine) {
        this.columnNameUnderLine = columnNameUnderLine;
    }

    public boolean isShowGeneratedSql() {
        return showGeneratedSql;
    }

    public void setShowGeneratedSql(boolean showGeneratedSql) {
        this.showGeneratedSql = showGeneratedSql;
    }

    public BaseDaoSqlInjector getBaseDaoSqlInjector() {
        try {
            return baseDaoSqlInjectorClass.newInstance();
        } catch (Exception e) {
            throw new MybatisMinusException(e);
        }
    }

    public void setBaseDaoSqlInjectorClass(Class<? extends BaseDaoSqlInjector> baseDaoSqlInjectorClass) {
        Assert.notNull(baseDaoSqlInjectorClass, "BaseDaoSqlInjector class can not be null");
        this.baseDaoSqlInjectorClass = baseDaoSqlInjectorClass;
    }

    public MethodNameSqlInjector getMethodNameSqlInjector() {
        try {
            return methodNameSqlInjectorClass.newInstance();
        } catch (Exception e) {
            throw new MybatisMinusException(e);
        }
    }

    public void setMethodNameSqlInjectorClass(Class<? extends MethodNameSqlInjector> methodNameSqlInjectorClass) {
        Assert.notNull(methodNameSqlInjectorClass, "MethodNameSqlInjector class can not be null");
        this.methodNameSqlInjectorClass = methodNameSqlInjectorClass;
    }

    public MinusMapperRegistry getMybatisMapperRegistry() {
        return mybatisMapperRegistry;
    }
}
